<?php
class CommonAction extends Action {
    
    protected $_str_model           = '';
    protected $_arr_where           = array();
    protected $_arr_search          = array();// array('db_field'=>array('condition', 'value', 'display_param_prefix', 'default_val'))
    protected $_str_status_type     = 'default';// all, default, bool, online

    /**
     * Init
     * 
     * @param  void
     * @return void
     * @author andy
     */
    protected function _initialize() {
             
        if ( ! User::check_login() ) {
            redirect('/login');   
        }

        $this->assign('str_login_user_name', get_login_user_name());
        $this->assign('int_login_user_id', get_login_user_id());
        $this->assign('str_php_environment', PHP_ENVIRONMENT);
        $this->assign('str_select_first_txt', '请选择');
        $this->assign('str_lookup', 'lookup');
        
        $this->assign('str_menu_html', User::get_login_user_info('menu_html'));
        $this->assign('str_page_html', '../app/Tpl/page.html');
        $this->assign('str_page_lookup_html', '../app/Tpl/page_lookup.html');
        $this->assign('str_page_search_html', '../app/Tpl/page_search.html');
        $this->assign('str_search_bar_html', '../app/Tpl/search_bar.html');
        $this->assign('str_search_bar_lookup_html', '../app/Tpl/search_bar_lookup.html');
        $this->assign('str_form_bar_html', '../app/Tpl/form_bar.html');
        $this->set_params();
    }
    
    /**
     * Set params
     * global settings, for index, edit, add
     * 
     * @param  void
     * @return void
     * @author andy
     */
    public function set_params() {
    }
    
    /**
     * Index page
     * 
     * @param  $strModel
     * @param  $arrWhere
     * @param  $strOrderBy
     * @param  $strStatusType
     * @return void
     * @author andy
     */
    public function index( $strModel = '', $arrWhere = array(), $strOrderBy = '', $strStatusType = '' ) {
        
        if ( ! User::check_role() ) {
            $this->_show_no_access();
        }
        
        if ( $this->_str_model ) {
            
            // Search
            $this->_search();

            // Page
            $int_page             = $this->_post('pageNum') ? $this->_post('pageNum') : 1;
            $int_per_page         = $this->_post('numPerPage') ? $this->_post('numPerPage') : 20;
            
            // List info
            $obj_model            = $this->_get_model($strModel);
            $arr_where            = $this->_get_where($arrWhere);
            $int_total            = $obj_model->get_total($arr_where);
            $arr_info             = $obj_model->get_list($int_page, $int_per_page, $arr_where, $strOrderBy);
            
            // Status info
            $str_status_type      = $this->_get_status_type($strStatusType);
            $arr_status           = $obj_model->get_status($str_status_type);
    
            $this->assign('int_page', $int_page);
            $this->assign('int_per_page', $int_per_page);
            $this->assign('int_total', $int_total);
            $this->assign('arr_info', $arr_info);
            $this->assign('arr_status', $arr_status);
        }

        $this->display();
    }
    
    /**
     * Lookup page
     * 
     * @param  $strModel
     * @param  $arrWhere
     * @param  $strOrderBy
     * @param  $strStatusType
     * @return void
     * @author andy
     */
    public function lookup( $strModel = '', $arrWhere = array(), $strOrderBy = '', $strStatusType = '' ) {
        
        $this->index($strModel, $arrWhere, $strOrderBy, $strStatusType);
    }
    
    /**
     * Detail page
     * 
     * @param  $strModel
     * @param  $strStatusType
     * @return void
     * @author andy
     */
    public function detail( $strModel = '', $strStatusType = '' ) {
        
        $this->edit($strModel, $strStatusType);
    }
    
    /**
     * Search before
     * 
     * @param  void
     * @return void
     * @author andy
     */
    public function before_search() {
    }
    
    /**
     * Do action before
     * for edit, add
     * 
     * @param  void
     * @return void
     * @author andy
     */
    public function before_do_action() {
    }
    
    /**
     * Add page
     * 
     * @param  $strModel
     * @param  $strStatusType
     * @return void
     * @author andy
     */
    public function add( $strModel = '', $strStatusType = '' ) {

        if ( ! User::check_role() ) {
            $this->_show_no_access();
        }
        
        $obj_model        = $this->_get_model($strModel);
        $str_status_type  = $this->_get_status_type($strStatusType);
        $arr_status       = $obj_model->get_status($str_status_type);

        $this->assign('arr_status', $arr_status);
        
        $this->display();
    }
    
    /**
     * Do add before
     * 
     * @param  void
     * @return void
     * @author andy
     */
    public function before_do_add() {
    }
    
    /**
     * Do add
     * 
     * @param  $strModel
     * @return void
     * @author andy
     */
    public function do_add( $strModel = '' ) {

        $this->before_do_action();
        $this->before_do_add();
        
        // Upload file
        $this->_upload_file();
        
        $obj_model     = $this->_get_model($strModel);
        
        // Start transaction
        $obj_model->start_trans();
        
        $obj_model->create();
        $arr_info      = $obj_model->get_data();
        $int_insert_id = $obj_model->add();
        
        if( ! $int_insert_id ) {
            
            // Rollback transaction
            $obj_model->rollback_trans();
            
            output_json_error(-10002, '操作失败！' . $obj_model->getDbError());
        }
        
        // Multi table
        // Media/DataGroupAlbum|album_id|id
        // Media/DataGroupAlbum|group_id
        // Media/DataGroupAlbum|display_order|data_group_album_display_order
        $arr_post_info = $this->_post();
        foreach ( $arr_post_info as $key=>$val ) {
            if ( stripos($key, '|') !== false ) {
                $arr_params                        = explode('|', $key);
                $str_action                        = $arr_params[0];
                $str_field                         = $arr_params[1];
                $str_field_val_key                 = $arr_params[2];
                
                if ( $str_field_val_key == 'id' ) {
                    $arr_post[$str_action][$str_field] = $int_insert_id;
                } else {
                    $arr_post[$str_action][$str_field] = $str_field_val_key ? $arr_post_info[$str_field_val_key] : $arr_post_info[$str_field];
                }
            }
        }
        
        // Process other table data
        if ( ! empty($arr_post) ) {
            
            foreach ( $arr_post as $key=>$sub ) {
                
                unset($_POST);
                foreach ( $sub as $str_field_name=>$str_field_val ) {
                    set_post($str_field_name, $str_field_val, false);
                }

                R($key . '/do_add');
            }
        }
        
        // Commit transaction
        $obj_model->commit_trans();
        
        log_db(__METHOD__, $int_insert_id, '添加', print_r($arr_info, true));
        
        output_json_info('操作成功！');
    }
    
    /**
     * Set params edit
     * 
     * @param  void
     * @return void
     * @author andy
     */
    public function set_params_edit() {
    }
    
    /**
     * Edit page
     * 
     * @param  $strModel
     * @param  $strStatusType
     * @return void
     * @author andy
     */
    public function edit( $strModel = '', $strStatusType = '' ) {

        if ( ! User::check_role() ) {
            $this->_show_no_access();
        }
        
        $int_id           = $this->_get('id');
        
        $obj_model        = $this->_get_model($strModel);
        $str_status_type  = $this->_get_status_type($strStatusType);
        $arr_info         = $obj_model->relation(true)->find($int_id);
        $arr_status       = $obj_model->get_status($str_status_type);

        $this->assign('arr_info', $arr_info);
        $this->assign('arr_status', $arr_status);
        $this->set_params_edit();
        
        $this->display();
    }
    
    /**
     * Do edit before
     * 
     * @param  void
     * @return void
     * @author andy
     */
    public function before_do_edit() {
    }
    
    /**
     * Do edit
     * 
     * @param  $strModel
     * @return void
     * @author andy
     */
    public function do_edit( $strModel = '' ) {

        $this->before_do_action();
        $this->before_do_edit();
        
        // Upload file
        $this->_upload_file();

        $obj_model  = $this->_get_model($strModel);
        
        // Start transaction
        $obj_model->start_trans();
        
        $obj_model->create('', 2);
        $arr_info   = $obj_model->get_data();
        $bln_result = $obj_model->save();

        if( ! $bln_result ) {
            
            // Rollback transaction
            $obj_model->rollback_trans();
            
            output_json_error(-20002, '操作失败！' . $obj_model->getDbError());
        } 
        
        // Multi table
        // Media/DataGroupAlbum|id|data_group_album_id
        // Media/DataGroupAlbum|group_id
        // Media/DataGroupAlbum|display_order|data_group_album_display_order
        $arr_post_info = $this->_post();
        foreach ( $arr_post_info as $key=>$val ) {
            if ( stripos($key, '|') !== false ) {
                $arr_params                        = explode('|', $key);
                $str_action                        = $arr_params[0];
                $str_field                         = $arr_params[1];
                $str_field_val_key                 = $arr_params[2];
                $arr_post[$str_action][$str_field] = $str_field_val_key ? $arr_post_info[$str_field_val_key] : $arr_post_info[$str_field];
            }
        }

        // Process other table data
        if ( ! empty($arr_post) ) {
            
            foreach ( $arr_post as $key=>$sub ) {
                
                unset($_POST);
                foreach ( $sub as $str_field_name=>$str_field_val ) {
                    set_post($str_field_name, $str_field_val, false);
                }

                R($key . '/do_edit');
            }
        }
        
        // Commit transaction
        $obj_model->commit_trans();
        
        log_db(__METHOD__, $arr_info['id'], '修改', print_r($arr_info, true));
        
        output_json_info('操作成功！');
    }
    
    /**
     * Edit all
     * 
     * @param  $strModel
     * @return void
     * @author andy
     */
    public function edit_all( $strModel = '' ) {

        if ( ! User::check_role() ) {
            $this->_show_no_access();
        }
        
        $obj_model        = $this->_get_model($strModel);
        $arr_info         = $obj_model->find();

        $this->assign('arr_info', $arr_info);
        
        $this->display();
    }
    
    /**
     * Do edit all
     * 
     * @param  $strModel
     * @return void
     * @author andy
     */
    public function do_edit_all( $strModel = '' ) {

        $this->before_do_action();
        
        $obj_model  = $this->_get_model($strModel);
        $obj_model->create('', 2);
        $arr_info   = $obj_model->get_data();
        $bln_result = $obj_model->where('status = 1')->save();
        
        if( ! $bln_result ) {
            
            output_json_error(-30001, '操作失败！' . $obj_model->getDbError());
        } 
        
        log_db(__METHOD__, '', '修改全部', print_r($arr_info, true));
        
        output_json_info('操作成功！');
    }
    
    /**
     * Edit multi
     * 
     * @param  $strModel
     * @return void
     * @author andy
     */
    public function edit_multi( $strModel = '' ) {

        if ( ! User::check_role() ) {
            $this->_show_no_access(true);
        }
        
        $str_ids          = $this->_post('ids');
        $arr_data         = $this->_get();

        if ( empty($str_ids) ) {
            output_json_error(-40002, '参数错误！');
        }

        $obj_model        = $this->_get_model($strModel);
        $bln_result       = $obj_model->where($obj_model->getPk() . ' IN (' . $str_ids . ')')->save($arr_data);

        if ( ! $bln_result ) {
            output_json_error(-40003, '批量修改错误！' . $obj_model->getDbError());
        }
        
        $arr_data['ids'] = $str_ids;
        log_db(__METHOD__, $str_ids, '批量修改', print_r($arr_data, true));
        
        output_json_info('操作成功！', false);
    }
    
    /**
     * Delete
     * 
     * @param  $strModel
     * @return void
     * @author andy
     */
    public function delete( $strModel = '' ) {

        if ( ! User::check_role() ) {
            $this->_show_no_access(true);
        }
        
        $int_id     = $this->_get('id');
        
        $obj_model  = $this->_get_model($strModel);
        $arr_info   = $obj_model->find($int_id);
        $bln_result = $obj_model->delete($int_id);
        
        if( ! $bln_result ) {
            
            output_json_error(-50002, '操作失败！' . $obj_model->getDbError());
        } 
        
        log_db(__METHOD__, $int_id, '删除', print_r($arr_info, true));
        
        output_json_info('操作成功！', false);
    }
    
    /**
     * Get page
     * 
     * @param  $intTotal
     * @param  $intPerPage
     * @return obj
     * @author andy
     */
    public function get_page( $intTotal, $intPerPage ) {
        
        import('ORG.Util.Page');
        
        return new Page($intTotal, $intPerPage);
    }
    
    /**
     * Get field info
     * get variable array, the definition of class, eg, $_arr_type]
     * 
     * $this->get_field_info('type')
     * 
     * @param  $strFieldName
     * @param  $strFieldInfoKey
     * @return array
     * @author andy
     */
    public function get_field_info( $strFieldName, $strFieldInfoKey = '' ) {

        $arr_info = $this->_get_model()->get_field_info($strFieldName, $strFieldInfoKey);

        return $arr_info;
    }
    
    /**
     * Get field info txt
     * to display type, status...
     * 
     * {$sub.type|call_action=get_field_info_txt,type}
     * 
     * @param  $strVal
     * @param  $strFieldType
     * @return mix
     * @author andy
     */
    public function get_field_info_txt( $strVal, $strFieldType ) {

        $arr_field_info = $this->_get_model()->get_field_info($strFieldType);

        return $arr_field_info[$strVal];
    }
    
    /**
     * Get model
     * 
     * @param  $strModel
     * @return obj
     * @author andy
     */
    private function _get_model( $strModel = '' ) {
        
        $str_model = $strModel ? $strModel : $this->_str_model;
        
        return D($str_model);
    }
    
    /**
     * Get where
     * 
     * @param  $arrWhere
     * @return string
     * @author andy
     */
    private function _get_where( $arrWhere = array() ) {
        
        return ! empty($arrWhere) ? $arrWhere : $this->_arr_where;
    }
    
    /**
     * Get status type
     * 
     * @param  $strStatusType
     * @return string
     * @author andy
     */
    private function _get_status_type( $strStatusType = '' ) {
        
        return ! empty($strStatusType) ? $strStatusType : $this->_str_status_type;
    }
    
    /**
     * Upload file
     * 
     * @param  void
     * @return void
     * @author andy
     */
    private function _upload_file() {
        
        if ( check_upload_file($_FILES) ) {
            
            // Upload file
            $arr_result = upload_file();
            $int_total  = count($_FILES);  
            
            for ( $i=0; $i<$int_total; $i++ ) {
                
                if ( $arr_result['status'] != 0 ) {
                    output_json_error($arr_result['status'], $arr_result['content']);
                }
                
                $arr_file = $arr_result['content'][$i];

                /*
                // Ftp
                if ( ! ftp( $arr_file['savename'], $arr_file['savename'] ) ) {
                    output_json_error(-10001, 'FTP上传失败！');
                }
                */

                // Set file
                $_POST[$arr_file['key']] = $arr_file['savename'];
            }
        }
    }
    
    /**
     * Search
     * 
     * @param  void
     * @return void
     * @author andy
     */
    private function _search() {
        
        $this->before_search();
        
        // Search
        if ( ! empty($this->_arr_search) ) {

            foreach ( $this->_arr_search as $str_field_name=>$sub ) {
                
                $str_condition          = $sub[0];
                $str_exp_val            = $sub[1];
                $str_display_param_pre  = $sub[2];
                $str_default_val        = $sub[3];
                $str_display_param      = $str_display_param_pre . '_' . $str_field_name;

                if ( ! $this->isPost() ) {
                    // 设置默认值
                    if ( $str_default_val ) {
                        $str_exp_val = str_replace('?', $str_default_val, $str_exp_val);
                        $this->assign($str_display_param, $str_default_val);
                        $this->_arr_where[$str_field_name] = array($str_condition, $str_exp_val);
                    }
                    continue;
                }
                
                $mix_post_val = is_array($this->_post($str_field_name)) ? $this->_post($str_field_name) : trim($this->_post($str_field_name));

                if ( $str_condition != 'BETWEEN' && ! empty($mix_post_val) || $mix_post_val == '0' ) {// 允许0值

                    $str_exp_val = str_replace('?', $mix_post_val, $str_exp_val);
                    $this->assign($str_display_param, $mix_post_val);
                    $this->_arr_where[$str_field_name] = array($str_condition, $str_exp_val);

                } else if ( $str_condition == 'BETWEEN' && ( ! empty($mix_post_val[0]) || ! empty($mix_post_val[1]) ) ) {// 2个值情况
                    
                    // $str_create_time_1, $str_create_time_2
                    foreach ( array(1, 2) as $key=>$val ) {
                        $str_post_val = $mix_post_val[$key] ? $mix_post_val[$key] : get_date();
                        $str_exp_val  = str_replace('?' . $val, $str_post_val, $str_exp_val);
                        $this->assign($str_display_param . '_' . $val, $str_post_val);
                    }
                    
                    $this->_arr_where[$str_field_name] = array($str_condition, $str_exp_val);
                }
            }
        }
    }
    
    /**
     * Show no access
     * 
     * @param  $blnAjax
     * @return void
     * @author andy
     */
    private function _show_no_access( $blnAjax = false ) {
        
        if ( $blnAjax ) {
            output_json_error(-80001, '没有权限！');
        } 
        
        $this->display(APP_PATH . '/Tpl/Error/no_access.html');
        exit;
    }
}